home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr05 / uniqwk20.zip / TALK.TXT < prev    next >
Text File  |  1993-07-07  |  13KB  |  409 lines

  1.                         Talkline - How it works.
  2.                         ~~~~~~~~~~~~~~~~~~~~~~~~
  3.  
  4.      Talkline is a sound of short duration, appended to the end of a message.
  5.      In this fist version, up to 5 seconds of sound can be added.
  6.      The purpose of this text file is to explain how the sound is coded
  7. and appended to the message.   This first version is called version "A" and
  8. has the following characterization:
  9.  
  10. 1-Sampling. - The sound bandwidth supports human voice only and so is sampled
  11.    at 5012.5Hz Hz, 8bits, with zero level at value 80h.
  12.  
  13. 2-Compression -
  14.    A - The signal is converted to 4 bits, first subtracting DC value (80h) and
  15.        using a log (base 2) conversion of the absolute value:
  16.             in           out
  17.                 0  ->  0
  18.           0.   .1  ->  1
  19.           2.   .3  ->  2
  20.           4.   .7  ->  3
  21.           8.  .15  ->  4
  22.          16.  .31  ->  5
  23.          32.  .63  ->  6
  24.          64. .127  ->  7
  25.        Now the signal is 4 bits with zero level at 0 (-16 to 15).
  26.  
  27.    B - The samples are packed 2 samples per byte, high nibble corresponding
  28.        to first sample and the low nibble to next one
  29.  
  30.         EX:
  31.         t = 0  0000hhhh  <-- 4 bit sample
  32.             1  0000LLLL
  33.  
  34.                 pack  ->  hhhhLLLL
  35.  
  36.    C - Run lenght encoded, using FFh as flag character.
  37.  
  38.        EX:
  39.        00 32 84 84 84 84 84 84 34 35 FF 54 54 FE FE FE FE FE FE
  40.  
  41.        is converted to:
  42.        00 32 FF 05 84 34 35 FF 01 FF 54 54 FF 06 FE
  43.  
  44. 3-Coding - The signal is coded using 7 bits, from 20h to 9Fh.
  45.  
  46.         EX:
  47.         0 - AAAAaaaa      - >   0 - 0AAAAaaa   +  30h
  48.         1 - BBBBbbbb            1 - 0BBBBbbb   +  30h
  49.         2 - CCCCcccc            2 - 0CCCCccc   +  30h
  50.         3 - DDDDdddd            3 - 0DDDDddd   +  30h
  51.         4 - EEEEeeee            4 - 0EEEEeee   +  30h
  52.         5 - FFFFffff            5 - 0FFFFfff   +  30h
  53.         6 - GGGGgggg            6 - 0GGGGggg   +  30h
  54.                                 7 - 0abcdefg   +  30h
  55.  
  56. 4-Saving - The result is appended to the end of message at 64 bytes per line,
  57.   with a header:
  58.  
  59.    "[TALK]"  - 6 bytes - Identify a talkline
  60.    1Bh,"[8m" - 4 bytes - ANSI command to disable output, to avoid trash on
  61.                mail readers/terminal emulators without sound capabilities.
  62.    "A"       - 1 byte  -  This version.   Letters A to H are reserved.
  63.    "00000"   - 5 bytes -  The size of the sound in bytes, after coding and
  64.                           without line feeds (E3h).
  65.    E3h       - 1 byte  -  The character used as LF by the QWK file format.
  66.  
  67.    .. follow first 64 bytes,E3h,  and so on...
  68.  
  69. =========================================================================
  70.  
  71.    As example, the routines, used  to compress and expand the voice signal.
  72.  
  73. //-----------------------------------------------------------------------
  74. UINT WaveCompress (LPSTR Pk, LPSTR Wav, UINT nS)
  75. //
  76. //      Wav - intput signal
  77. //      Pk  - output signal
  78. //      nS  - number of data points
  79. //
  80. {
  81.   register UINT k, T;
  82.   char M;
  83.   UINT Ncomp, nS;
  84.  
  85.   Log2(Wav, nS);                        ;4 bit convert
  86.   Ncomp = nS >> 1;
  87. //                                      pack data
  88.   _asm  {
  89.             LES   SI,Wav        ;ES:SI -> Wav
  90.             MOV   DI,SI
  91.             MOV   CX,Ncomp
  92.             JCXZ  DONE
  93.      L1:    MOV   AX,ES:[SI]
  94.             SHL   AL,4          ;shift to HI nibble
  95.             AND   AX,0FF0h      ;mask
  96.             OR    AL,AH         ;merge
  97.             STOSB               ;save
  98.             ADD   SI,2
  99.             LOOP  L1
  100.      DONE:
  101.          }
  102. //
  103.   nS = 0;
  104.   Wav[Ncomp] = (char)(Wav[Ncomp-1]+1);  //make last different
  105.   for(k=0; k<Ncomp; k++)                //run lenght encode
  106.   {  T = 1;
  107.      M = Wav[k];
  108.      while (M == Wav[k+T])              //iqual next?
  109.      { if(T == 253) break;
  110.        else T = T + 1;                  //yes, bump T
  111.      }
  112.      if(T > 2 || M == '\xFF')
  113.      { Wav[nS++] = 0xFF;                //mark
  114.        Wav[nS++] =(char)T;              //total
  115.        k = k + T - 1;                   //next
  116.      }
  117.      Wav[nS++] = M;                     //save data
  118.   }
  119.   Ncomp = Pack(Pk, Wav, nS);            //7 bits convert
  120.   return Ncomp;
  121. }
  122. //-----------------------------------------------------------------
  123. LONG WaveExpand (LPSTR Wav, LPSTR Pk, UINT nS)
  124. //
  125. //      Pk  - input signal
  126. //      Wav - output signal
  127. //      nS  - number of data points
  128. //
  129. {
  130.   register UINT T, k;
  131.   UINT Cnt;
  132.   LONG nExp, Pt;
  133.  
  134. //
  135.    nSamp = Unpack(Pk, Pk, nSamp);             // 8 bits convert
  136.    nExp = 0;                                  // run lenght decode
  137.    for(Pt=0; (UINT)Pt < nSamp; Pt++)
  138.    {  if(Pk[Pt] == (char) 0xFF )
  139.       { Cnt = (BYTE) Pk[++Pt];
  140.         T = (char)Pk[++Pt];
  141.         for(k = 0; k < Cnt; k++) Wav[nExp++] = (char)T;
  142.       }
  143.       else
  144.       { Wav[nExp++] = Pk[Pt]; }
  145.    }
  146.    Cnt =(UINT)nExp;                           //unpack
  147.    _asm {
  148.             LES   DI, Wav
  149.             MOV   BX,Cnt
  150.             OR    BX,BX
  151.             JZ    DONE
  152.             MOV   SI,DI
  153.             ADD   SI,BX         ;end of data
  154.             ADD   BX,BX         ;end of unpacked data
  155.      L1:    MOV   AL,ES:[SI]
  156.             MOV   AH,AL         ;copy
  157.             SHR   AL,4          ;do inverse operation
  158.             AND   AX,0F0Fh     ;mask
  159.             MOV   ES:[DI+BX],AX ;save
  160.             DEC   SI
  161.             SUB   BX,2
  162.             JAE   L1            ;for all data points
  163.      DONE:
  164.         }
  165. //
  166.    nExp = nExp + nExp;
  167.    Exp2(Wave, nExp);                            ;8 bit convert
  168.    return nExp;
  169. }
  170. //=======================================================================
  171.  
  172.         Assebly routines to convert to and from 7 bits.
  173.  
  174. ;-------------------------------------------------------------------------
  175. ;       UINT = Pack (LPSTR, LPSTR, UINT);
  176. ;
  177. _Pack   PROC    FAR
  178.         PUSH    BP
  179.         MOV     BP,SP
  180.         PUSHF
  181.         CLD                     ;up
  182.         PUSH    DS
  183.         PUSH    SI
  184.         PUSH    DI
  185.         XOR     AX,AX           ;zero return value
  186.         MOV     CX,[BP+14]      ;size  (up to 64k)
  187.         JCXZ    PACK9
  188.         LES     DI,[BP+6];
  189.         LDS     SI,[BP+10];     ;DS:SI -> string
  190.         XOR     BX,BX           ;byte count
  191.         ADD     CX,SI           ;offset end of input string
  192.         PUSH    DI              ;save it
  193. ;
  194. PACK1:  MOV     DX,BX           ;insert a 0E3h each 64 bytes
  195.         AND     DX,3FH          ;test
  196.         JNZ     @F
  197.         MOV     AL,0E3h         ;LF (on QWK...)
  198.         STOSB                   ;insert
  199. @@:     CMP     SI,CX           ;end of processing?
  200.         JAE     PACK2           
  201.         LODSW                   ;-- 1 & 2
  202.         SHR     AL,1            ;-> 7, bit 0 to CY
  203.         RCL     DH,1            ;CY to bit 0 on DH
  204.         SHR     AH,1            ;repeat to next byte
  205.         RCL     DH,1
  206.         ADD     AX,3030h        ;translate to 30-A0h
  207.         STOSW                   ;ok, save it
  208.         LODSW
  209.         SHR     AL,1            ;repeat for bytes 3 & 4
  210.         RCL     DH,1
  211.         SHR     AH,1
  212.         RCL     DH,1
  213.         ADD     AX,3030h
  214.         STOSW
  215.         LODSW
  216.         SHR     AL,1            ;and 5 & 6
  217.         RCL     DH,1
  218.         SHR     AH,1
  219.         RCL     DH,1
  220.         ADD     AX,3030h
  221.         STOSW
  222.         LODSB
  223.         SHR     AL,1            ;the last one...
  224.         RCL     DH,1            ;
  225.         MOV     AH,DH           ;save DH (7 saved bits)
  226.         ADD     AX,3030h        ;
  227.         STOSW                   ;
  228.         ADD     BX,8            ;total
  229.         JMP     PACK1
  230. PACK2:  MOV     AX,DI           ;new position
  231.         POP     DI              ;initial position
  232.         SUB     AX,DI           ;return total processed bytes
  233. PACK9:  XOR     DX,DX           ;AX:DX
  234.         POP     DI
  235.         POP     SI
  236.         POP     DS
  237.         POPF
  238.         MOV     SP,BP
  239.         POP     BP
  240.         RET
  241. _Pack   ENDP
  242. ;-------------------------------------------------------------
  243. ;       UINT = Unpack (LPSTR, LPSTR, UINT);
  244. ;
  245. _Unpack PROC    FAR
  246.         PUSH    BP
  247.         MOV     BP,SP
  248.         PUSHF
  249.         PUSH    DS
  250.         PUSH    SI
  251.         PUSH    DI
  252.         CLD                     ;up
  253.         XOR     AX,AX
  254.         MOV     CX,[BP+14]      ;size
  255.         JCXZ    UNPCK9
  256.         LES     DI,[BP+6];      ;ES:DI -> string
  257.         LDS     SI,[BP+10];     ;DS:SI -> string
  258.         PUSH    DI
  259. UNPCK0: LODSB
  260.         CMP     AL,30H          ;if out of range (30h -> AFh)
  261.         JB      @F              ;do not copy
  262.         CMP     AL,0B0H
  263.         JA      @F
  264.         STOSB
  265. @@:     LOOP    UNPCK0
  266.         MOV     AX,DI
  267.         POP     DI
  268.         SUB     AX,DI           ;total "clean" bytes
  269.         LDS     SI,[BP+6]
  270.         LES     DI,[BP+6]       ;works only on destination
  271.         ADD     AX,7
  272.         SHR     AX,3            ;number of loops
  273.         MOV     CX,AX
  274.         MOV     BX,7
  275.         MUL     BX              ;number of bytes
  276.         MOV     BX,AX           ;save on BX
  277. UNPCK1: MOV     DH,[SI+7]       ;get saved bit
  278.         SUB     DH,30h          ;convert to 0 - 7Fh
  279.         RCL     DH,1
  280.         LODSW
  281.         SUB     AX,3030h        ;convert data too
  282.         RCL     DH,1            ;bit -> CY
  283.         RCL     AL,1            ;insert on byte
  284.         RCL     DH,1            ;next byte
  285.         RCL     AH,1
  286.         STOSW                   ;save
  287.         LODSW
  288.         SUB     AX,3030h        ;next 2 bytes
  289.         RCL     DH,1
  290.         RCL     AL,1
  291.         RCL     DH,1
  292.         RCL     AH,1
  293.         STOSW
  294.         LODSW
  295.         SUB     AX,3030h        ;bytes 5 & 6
  296.         RCL     DH,1
  297.         RCL     AL,1
  298.         RCL     DH,1
  299.         RCL     AH,1
  300.         STOSW
  301.         LODSW
  302.         SUB     AL,30h          ;the last...
  303.         RCL     DH,1
  304.         RCL     AL,1
  305.         STOSB
  306.         LOOP    UNPCK1          ;repeat all
  307.         MOV     AX,BX
  308. UNPCK9: XOR     DX,DX           ;return total processed.
  309.         POP     DI
  310.         POP     SI
  311.         POP     DS
  312.         POPF
  313.         MOV     SP,BP
  314.         POP     BP
  315.         RET
  316. _Unpack ENDP
  317. ;---------------------------------------------------------------------
  318. ;       Assembly routines to convert from 8 to 4 bits and from 4 to 8
  319. ;---------------------------------------------------------------------
  320. ;       Log2 (LPSTR, UINT);
  321. ;
  322. _Log2   PROC    FAR
  323.         PUSH    BP
  324.         MOV     BP,SP
  325.         PUSHF
  326.         PUSH    ES
  327.         PUSH    DI
  328.         CLD
  329.         MOV     BX,[BP+10]      ;size to CX
  330.         OR      BX,BX
  331.         JZ      LOGC9
  332.         LES     DI,[BP+6];      ;ES:DI -> in/out - in place conversion
  333. LOGC1:  MOV     AL,ES:[DI]
  334.         XOR     CH,CH           ;zero
  335.         MOV     DL,CH           ;
  336.         sub     al,80h          ;remove DC value (-128..127)
  337.         OR      AL,AL
  338.         JNS     @F              ;if positive, go
  339.         NEG     AL              ;signal change
  340.         MOV     DL,8            ;signal bit
  341. @@:     AND     AL,7FH
  342.         SHL     AL,1
  343.         MOV     CL,7
  344. @@:     SHL     AL,1
  345.         JC      @F
  346.         LOOP    @B
  347. @@:     OR      CL,DL           ;insert signal
  348.         MOV     AL,CL
  349. ;
  350.         STOSB                   ;save
  351.         DEC     BX              ;end test
  352.         JNZ     LOGC1           ;no, more...
  353. LOGC9:  POP     DI
  354.         POP     ES
  355.         POPF
  356.         MOV     SP,BP
  357.         POP     BP
  358.         RET
  359. _Log2   ENDP
  360. ;-------------------------------------------------------------------
  361. ;       Exp2 (LPSTR, UINT);
  362. ;
  363. _LogExp PROC    FAR
  364.         PUSH    BP
  365.         MOV     BP,SP
  366.         PUSHF
  367.         PUSH    ES
  368.         PUSH    DI
  369.         CLD                     ;up
  370.         XOR     AX,AX
  371.         MOV     BX,[BP+10]      ;size
  372.         OR      BX,BX
  373.         JZ      LOGE9
  374.         LES     DI,[BP+6];      ;ES:DI -> in/out
  375.         XOR     CH,CH
  376. LOGE1:  MOV     AL,ES:[DI]
  377.         XOR     AH,AH
  378. ;
  379.         MOV     CL,AL           ;copy
  380.         AND     CL,7            ;signal mask
  381.         STC
  382.         RCL     AH,CL           ;exp
  383.         TEST    AL,8
  384.         JZ      @F              ;if positive
  385.         NEG     AH
  386. @@:     ADD     AH,80H          ;recover offset
  387.         MOV     AL,AH
  388.         STOSB                   ;save
  389.         DEC     BX
  390.         JNZ     LOGE1           ;loop
  391. LOGE9:  POP     DI
  392.         POP     ES
  393.         POPF
  394.         MOV     SP,BP
  395.         POP     BP
  396.         RET
  397. _Exp2   ENDP
  398. ;========================================================================
  399.  
  400. OBS: The music appended to the end of messages is a .MID file only coded
  401. into 7 bits.  The file header is the same, only the identifier "TALK" is
  402. changed to "MIDI".
  403.  
  404.  
  405. ==========================================================================
  406.                                             Carlos Pires, Rio, March 1993.
  407. ==========================================================================
  408.  
  409.